package com.crawler.crawler.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


import com.crawler.crawler.domain.BooksConfigs;
import com.crawler.crawler.service.IBooksConfigsService;
import com.crawler.crawler.util.DateUtils;
import com.crawler.crawler.util.FileDownload;
import org.jsoup.Jsoup;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.crawler.crawler.mapper.BooksAibooksMapper;
import com.crawler.crawler.domain.BooksAibooks;
import com.crawler.crawler.service.IBooksAibooksService;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * AibooksService业务层处理
 * 
 * @author XUEH
 * @date 2020-10-14
 */
@Service
public class BooksAibooksServiceImpl implements IBooksAibooksService 
{
    @Autowired
    private BooksAibooksMapper booksAibooksMapper;

    @Autowired
    private IBooksConfigsService booksConfigsService;
    /**
     * 查询Aibooks
     * 
     * @param id AibooksID
     * @return Aibooks
     */
    @Override
    public BooksAibooks selectBooksAibooksById(Long id)
    {
        return booksAibooksMapper.selectBooksAibooksById(id);
    }

    /**
     * 查询Aibooks列表
     * 
     * @param booksAibooks Aibooks
     * @return Aibooks
     */
    @Override
    public List<BooksAibooks> selectBooksAibooksList(BooksAibooks booksAibooks)
    {
        return booksAibooksMapper.selectBooksAibooksList(booksAibooks);
    }

    /**
     * 新增Aibooks
     * 
     * @param booksAibooks Aibooks
     * @return 结果
     */
    @Override
    public int insertBooksAibooks(BooksAibooks booksAibooks)
    {
        booksAibooks.setCreateTime(DateUtils.getNowDate());
        return booksAibooksMapper.insertBooksAibooks(booksAibooks);
    }

    /**
     * 修改Aibooks
     * 
     * @param booksAibooks Aibooks
     * @return 结果
     */
    @Override
    public int updateBooksAibooks(BooksAibooks booksAibooks)
    {
        return booksAibooksMapper.updateBooksAibooks(booksAibooks);
    }

    /**
     * 批量删除Aibooks
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteBooksAibooksByIds(String ids) {
        return 0;
    }


    /**
     * 删除Aibooks信息
     * 
     * @param id AibooksID
     * @return 结果
     */
    @Override
    public int deleteBooksAibooksById(Long id)
    {
        return booksAibooksMapper.deleteBooksAibooksById(id);
    }

    /**
     * 执行爬虫
     * @return
     */
    @Override
    public String crawl(){
        Map<String,String> map=booksConfigsService.selectBooksConfigsForMap();
        String url= map.get("aibooksUrl");
        int startIndex= Integer.parseInt(map.get("aibooksStartPage"));
        boolean go=true;
        String childUrl=url;
            while (go){
                if(startIndex>1){
                    childUrl=url+"/page/"+startIndex;
                }

                //得到图书列表
                List<String> bookUrlList=getBookList(childUrl);
                if(bookUrlList.size()>0){
                    //循环图书列表
                    for (int k=0;k<bookUrlList.size();k++){
                        //查询是否已在数据库
                        BooksAibooks searchBook=new BooksAibooks();
                        searchBook.setUrl(bookUrlList.get(k));
                        List<BooksAibooks> oldBook= selectBooksAibooksList(searchBook);

                        if(oldBook.size()==0){
                            getBookInfo(bookUrlList.get(k),startIndex,map.get("coverPath"));
                        }

                    }
                    //将页数存入数据库，以便后使用
                    startIndex++;
                    BooksConfigs configs=new BooksConfigs();
                    configs.setId((long) 1);
                    configs.setValue(String.valueOf(startIndex));
                    booksConfigsService.updateBooksConfigs(configs);
                }else {
                    go=false;
                }
            }
        return "success";
    }



    /**
     * 读取图书地址
     *
     * @param url
     */
    public List<String> getBookList(String url) {
        List<String> bookList = new ArrayList<String>();

        Map<String,String> map=booksConfigsService.selectBooksConfigsForMap();
        System.setProperty("webdriver.chrome.driver",map.get("chromeDriverPath"));
// ChromeOptions
        ChromeOptions chromeOptions = new ChromeOptions();
// 设置后台静默模式启动浏览器
        chromeOptions.addArguments("--headless");
        WebDriver driver =new ChromeDriver(chromeOptions);
//        driver.get(url); // 打开指定的网站
        driver.get(url);// 打开指定的网站        
        try {
            /**
             * WebDriver自带了一个智能等待的方法。 dr.manage().timeouts().implicitlyWait(arg0, arg1）；
             * Arg0：等待的时间长度，int 类型 ； Arg1：等待时间的单位 TimeUnit.SECONDS 一般用秒作为单位。
             */
            driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //获取当前浏览器的信息
        System.out.println("Title:" + driver.getTitle());
        System.out.println("currentUrl:" + driver.getCurrentUrl());

        //获取多个元素
        List<WebElement> element = driver.findElements(By.className("thumb-img"));
        for (WebElement e : element) {
            String bookListHtml = e.getAttribute("innerHTML");
            Document document = Jsoup.parse(bookListHtml);
            //得到第二个a标签数据
            String bookUrl = document.select("a[href]:eq(1)").attr("href");
            bookList.add(bookUrl);
        }
        driver.quit();
        //返回图书地址合集
        return bookList;
    }
    /**
     * 读取图书页面
     *
     * @param url
     * @param page
     * @param filePath
     */
    public void getBookInfo(String url, int page, String filePath) {
        System.out.println("开始执行"+url);
        Map<String,String> map=booksConfigsService.selectBooksConfigsForMap();
        System.setProperty("webdriver.chrome.driver",map.get("chromeDriverPath"));
// ChromeOptions
        ChromeOptions chromeOptions = new ChromeOptions();
// 设置后台静默模式启动浏览器
        chromeOptions.addArguments("--headless");
        WebDriver driver =new ChromeDriver(chromeOptions);
        driver.get(url); // 打开指定的网站
        try {
            /**
             * WebDriver自带了一个智能等待的方法。 dr.manage().timeouts().implicitlyWait(arg0, arg1）；
             * Arg0：等待的时间长度，int 类型 ； Arg1：等待时间的单位 TimeUnit.SECONDS 一般用秒作为单位。
             */
            driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);


            //获取当前浏览器的信息
            System.out.println("Title:" + driver.getTitle());
            System.out.println("currentUrl:" + driver.getCurrentUrl());

            //填写验证码
            try {

                driver.findElement(By.id("verifycode")).sendKeys(map.get("aibooksKey"));
                driver.findElement(By.id("verifybtn")).click();
            }catch (Exception e){

            }


            //========================获取图书信息=======================
            //分类
            String cat = driver.findElement(By.xpath("//*[@id=\"mute-category\"]/a")).getAttribute("innerHTML");
            //图片
            String imgUrl = driver.findElement(By.xpath("/html/body/section/div[2]/div/header/div[2]/div[1]/div/div[1]/img")).getAttribute("src");
            //下载图片


            //书名
            String bookNameStrong = driver.findElement(By.xpath("/html/body/section/div[2]/div/header/div[2]/div[1]/div/div[2]/ul/li[1]")).getAttribute("innerHTML");
            String bookName = bookNameStrong.replaceAll("<strong>书名：", "");
            bookName = bookName.replaceAll("</strong>", "");
            String bookCover = FileDownload.downloadPicture1(imgUrl, filePath,bookName);
            //作者
            String author="";
            try {

            }catch (Exception e){
                 String authorStrong = driver.findElement(By.xpath("/html/body/section/div[2]/div/header/div[2]/div[1]/div/div[2]/ul/li[2]")).getAttribute("innerHTML");
                 author = authorStrong.replaceAll("<strong>作者：</strong>", "");
            }

            //标签
            String tags="";
            try {
                String tagsStrong = driver.findElement(By.className("article-tags")).getAttribute("innerHTML");
                String tagsStrongs = tagsStrong.replaceAll("<strong>标签：</strong>", "");
                Document document = Jsoup.parse(tagsStrongs);
                Elements elements = document.select("a[href]");

                StringBuilder tagsBuilder = new StringBuilder();
                int elementCount = 1;
                for (Element element : elements) {
                    //得到A标签中的文本
                    if (elementCount > 1) {
                        tagsBuilder.append(",");
                    }
                    tagsBuilder.append(element.text());
                    elementCount++;
                }
                tags = tagsBuilder.toString();
            }catch (Exception e){

            }




            //ISBN
            String isbn="";
            try {
                isbn = driver.findElement(By.xpath("/html/body/section/div[2]/div/header/div[2]/div[1]/div/div[2]/ul/li[8]")).getAttribute("innerHTML");
                isbn = isbn.replaceAll("<strong>ISBN：</strong>", "");

            }catch (Exception e){

            }

            //出版时间
            String  publishTime="";
            try {
                publishTime=driver.findElement(By.xpath("/html/body/section/div[2]/div/header/div[2]/div[1]/div/div[2]/ul/li[6]")).getAttribute("innerHTML");
                publishTime = publishTime.replaceAll("<strong>出版年：</strong>", "");
            }catch (Exception e){

            }

            //出版社
            String  publisher="";
            try {
                publisher=driver.findElement(By.xpath("/html/body/section/div[2]/div/header/div[2]/div[1]/div/div[2]/ul/li[5]")).getAttribute("innerHTML");
                publisher = publisher.replaceAll("<strong>出版社：</strong>", "");
            }catch (Exception e){

            }
            String allHtml = driver.findElement(By.xpath("/html/body/section/div[2]/div/article")).getAttribute("innerHTML");
            String authorValidity = "";
            String contentValidity = "";
            //有内容简介时，则填写内容简介
            if (allHtml.indexOf("<h2>内容简介</h2>") > -1) {
                String articleHtml = allHtml.split("<h2>内容简介</h2>")[1];

                if (articleHtml.indexOf("<h2>作者简介</h2>") > -1) {
                    String[] articleHtml_1 = articleHtml.split("<h2>作者简介</h2>");
                    //内容简介
                    contentValidity = articleHtml_1[0];
                    //作者简介
                    String[] articleHtml_2 = articleHtml_1[1].split("<table class=\"dltable\"><tbody>");
                    authorValidity = articleHtml_2[0];
                } else {
                    //内容简介
                    contentValidity = articleHtml.split("<table class=\"dltable\"><tbody>")[0];
                }
            } else if (allHtml.indexOf("<h2>作者简介</h2>") > -1) {
                String[] articleHtml_1 = allHtml.split("<h2>作者简介</h2>");
                //作者简介
                String[] articleHtml_2 = articleHtml_1[1].split("<table class=\"dltable\"><tbody>");
                authorValidity = articleHtml_2[0];
            }



            //百度云盘验证码
            String yunCode = "";
            String lanzousCode = "";
            String codeString="";
            try {
                codeString=driver.findElement(By.className("alert-success")).getAttribute("innerHTML");
            }catch(Exception e){
            }

            String[] codeArray=codeString.split("<br>");
            if(codeArray.length==2){
                yunCode=codeArray[0].replace("百度提取码：", "");
                lanzousCode=codeArray[1].replace("蓝奏提取码：", "");

            }else if(codeArray.length==1){
                yunCode=codeArray[0].replace("百度提取码：", "");
            }
            String baiduyunUrl = "";
            try {
                baiduyunUrl = driver.findElement(By.xpath("//a[text()='百度云盘']")).getAttribute("href");
            } catch (Exception e) {

            }

            String lanzousUrl = "";
            try {
                lanzousUrl = driver.findElement(By.xpath("//a[text()='蓝奏云盘']")).getAttribute("href");
            } catch (Exception e) {

            }

            //保存数据到数据库中
            BooksAibooks book = new BooksAibooks();
            book.setTitle(bookName);
            book.setBaiduCode(yunCode);
            book.setAuthor(author);
            book.setAuthorContent(authorValidity);
            book.setType(cat);
            book.setBaiduUrl(baiduyunUrl);
            book.setCover(bookCover);
            book.setIsbn(isbn);
            book.setContent(contentValidity);
            book.setTags(tags);
            book.setUrl(driver.getCurrentUrl());
            book.setPublisher(publisher);
            book.setPublishTime(publishTime);
            book.setPage(Long.valueOf(page));
            book.setLanzousCode(lanzousCode);
            book.setLanzousUrl(lanzousUrl);
            //保存数据
            insertBooksAibooks(book);
            System.out.println("====================================");
            System.out.println(bookName);
            System.out.println(url);
            System.out.println("已执行完成"+url);
            System.out.println();
            driver.quit();
        } catch (Exception e) {
            driver.quit();
            this.crawl();
        }
    }


}
